/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.seari.utils;

import com.gargoylesoftware.htmlunit.*;
import com.gargoylesoftware.htmlunit.html.*;
import com.gargoylesoftware.htmlunit.util.*;
import com.seari.utils.common.SimpleWebClient;
import java.awt.image.*;
import java.io.*;
import java.security.*;
import java.security.cert.*;
import java.sql.*;
import java.util.*;
import java.util.regex.*;
import javax.imageio.*;
import javax.net.ssl.*;
import org.apache.commons.lang3.StringUtils;

/**
 *
 * @author sunzhu
 */
public class HtmlTools
{
    
    /**
     * 从img标签获取图像，静态图片输出为png格式字节数组，动画gif，输出动画gif格式的字节数组
     * @param hi
     * @return
     * @throws Exception 
     */
//    public static byte[] getImageData(HtmlImage hi) throws Exception
//    {
//        List<BufferedImage> imgs = hi.getImages();
//        ByteArrayOutputStream baos = new ByteArrayOutputStream();
//        if(imgs.size()==1)
//        {            
//            ImageIO.write(imgs.get(0), "png", baos);
//            baos.flush();
//        }
//        else
//            ImageUtils.saveAnimatedImage(baos, imgs.toArray(new BufferedImage[0]));
//        byte[] img = baos.toByteArray();
//        baos.close();
//        return img;
//    }


    

    /**
     * 手工创建WebResponse
     * @param wr
     * @param content
     * @param contentType
     * @param oldHeaders
     * @return
     * @throws IOException 
     */
    public static WebResponse createWebResponse(final WebRequest wr, final String content, final String contentType,
            List<NameValuePair> oldHeaders) throws IOException
    {
        List<NameValuePair> headers = new ArrayList<NameValuePair>();
        String encoding = "UTF-8";
        for (NameValuePair header : oldHeaders)
        {
            if ("content-type".equalsIgnoreCase(header.getName()))
                headers.add(new NameValuePair("content-type", contentType + "; charset=" + encoding));
            else
                headers.add(header);
        }

        byte[] body = content.getBytes(encoding);
        WebResponseData wrd = new WebResponseData(body, 200, "OK", headers);
        return new WebResponse(wrd, wr.getUrl(), wr.getHttpMethod(), 0);
    }

    /**
     * 创建空的WebResponse
     * @param wr
     * @return
     * @throws IOException 
     */
    public static WebResponse createEmptyWebResponse(final WebRequest wr) throws IOException
    {
        List<NameValuePair> headers = new ArrayList<NameValuePair>();
        byte[] body = "".getBytes();
        WebResponseData wrd = new WebResponseData(body, 200, "OK", headers);
        return new WebResponse(wrd, wr.getUrl(), wr.getHttpMethod(), 0);
    }

    /**
     * 将cookie保存为文件
     * @param cookies
     * @param fileName
     * @throws Exception 
     */
    public static void saveCookies(Set<Cookie> cookies, String fileName) throws Exception
    {
        ObjectOutput out = new ObjectOutputStream(new FileOutputStream(fileName));
        out.writeObject(cookies);
        out.close();
    }

    /**
     * 从文件读取已保存的cookie
     * @param fileName
     * @return
     * @throws Exception 
     */
    public static Set<Cookie> loadCookies(String fileName) throws Exception
    {
        File file = new File(fileName);
        if (!file.exists())
            throw new Exception("No cookie file found!");
        ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
        try
        {
            Set<Cookie> cookies=(Set<Cookie>) in.readObject();
            return cookies;
        }
        finally
        {
            in.close();
        }
    }
    
    /**
     * 将指定的cookie文件导入WebClient
     * @param client
     * @param cookieFile
     * @throws Exception 
     */
    public static void loadCookiesToWebClient(WebClient client, String cookieFile) throws Exception
    {
        Set<Cookie> cookies=loadCookies(cookieFile);
        Iterator<Cookie> c=cookies.iterator();
        while(c.hasNext())
        {
            client.getCookieManager().addCookie(c.next());
        }
    }
    
    static final String REGEX_SCRIPT = "<script[^>]*?>[\\s\\S]*?<\\/script>"; //定义script的正则表达式 
    static final String REGEX_STYLE = "<style[^>]*?>[\\s\\S]*?<\\/style>"; //定义style的正则表达式 
    static final String REGEX_WORD = "&\\w{1,7};";
    static final String REGEX_HTML = "<[^>]+>"; //定义HTML标签的正则表达式 
    static final String REGEX_DEL_BLANK = "\\s";
    static final Pattern PATTERN_SCRIPT = Pattern.compile(REGEX_SCRIPT, Pattern.CASE_INSENSITIVE);
    static final Pattern PATTERN_STYLE = Pattern.compile(REGEX_STYLE, Pattern.CASE_INSENSITIVE);
    static final Pattern PATTERN_HTML = Pattern.compile(REGEX_HTML, Pattern.CASE_INSENSITIVE);
    static final Pattern PATTERN_WORD = Pattern.compile(REGEX_WORD, Pattern.CASE_INSENSITIVE);
    static final Pattern PATTERN_BLANK = Pattern.compile(REGEX_DEL_BLANK, Pattern.CASE_INSENSITIVE);

    /**
     * 过滤html标签
     * @param htmlStr
     * @return 
     */
    public static String removeHtmlTag(String htmlStr)
    {
        if (StringUtils.isBlank(htmlStr))
            return "";
        Matcher m_script = PATTERN_SCRIPT.matcher(htmlStr);
        htmlStr = m_script.replaceAll(""); //过滤script标签 

        Matcher m_style = PATTERN_STYLE.matcher(htmlStr);
        htmlStr = m_style.replaceAll(""); //过滤style标签 

        Matcher m_html = PATTERN_HTML.matcher(htmlStr);
        htmlStr = m_html.replaceAll(""); //过滤html标签  

        Matcher m_word = PATTERN_WORD.matcher(htmlStr);
        htmlStr = m_word.replaceAll(""); //过滤各种占位符标签

        Matcher m_blank_space = PATTERN_BLANK.matcher(htmlStr);
        htmlStr = m_blank_space.replaceAll(""); //过滤各种占位符标签      

        /**
         * htmlStr = htmlStr.replaceAll("&ldquo;", ""); htmlStr = htmlStr.replaceAll("&nbsp;", ""); htmlStr = htmlStr.replaceAll("&mdash;",
         * ""); htmlStr = htmlStr.replaceAll("&hellip;", ""); htmlStr = htmlStr.replaceAll("&rdquo;", ""); htmlStr =
         * htmlStr.replaceAll("&lsquo;", ""); htmlStr = htmlStr.replaceAll("&rsquo;", ""); htmlStr = htmlStr.replaceAll("&", "");
         */
        return htmlStr.trim(); //返回文本字符串 
    }
    
    /**
     * 过滤html标签
     * @param htmlStr
     * @return 
     */
    public static String removeHtmlScript(String htmlStr)
    {
        if (StringUtils.isBlank(htmlStr))
            return "";
        Matcher m_script = PATTERN_SCRIPT.matcher(htmlStr);
        htmlStr = m_script.replaceAll(""); //过滤script标签 

        Matcher m_style = PATTERN_STYLE.matcher(htmlStr);
        htmlStr = m_style.replaceAll(""); //过滤style标签 

        Matcher m_word = PATTERN_WORD.matcher(htmlStr);
        htmlStr = m_word.replaceAll(""); //过滤各种占位符标签  
        return htmlStr.trim(); //返回文本字符串 
    }
    
   
    
    /**
     * 通过cyyun公共服务识别验证码
     * @param fid
     * @param gid
     * @param url
     * @param img
     * @return
     * @throws Exception 
     */
    public static String crackCaptcharFromService(int fid, int gid, String url, byte[] img) throws Exception
    {
        SimpleWebClient wc=new SimpleWebClient();
        wc.addHeader("X-Captchar-Url", url);
        try
        {
            return wc.getResponseForPost("http://www.cyyun.com/publicsvc/captchar?fid="+fid+"&gid="+gid, img);
        }
        catch (Exception e)
        {
            throw e;
        }
        finally
        {
            wc.close();
        }
    }
    
    /**
     * 禁用SSL证书验证
     */
    public static void disableCertificateValidation()
    {
        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts=new TrustManager[]
        {
            new X509TrustManager()
            {
                @Override
                public X509Certificate[] getAcceptedIssuers()
                {
                    return new X509Certificate[0];
                }

                @Override
                public void checkClientTrusted(X509Certificate[] certs, String authType)
                {
                }

                @Override
                public void checkServerTrusted(X509Certificate[] certs, String authType)
                {
                }
            }
        };

        // Ignore differences between given hostname and certificate hostname
        HostnameVerifier hv=new HostnameVerifier()
        {
            @Override
            public boolean verify(String hostname, SSLSession session)
            {
                return true;
            }
        };

        // Install the all-trusting trust manager
        try
        {
            SSLContext sc=SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            HttpsURLConnection.setDefaultHostnameVerifier(hv);
        }
        catch(Exception e)
        {
        }
    }

    /**
     * 关闭页面
     * @param page 
     */
    public static void closeWebPage(SgmlPage page)
    {
        if (page != null)
        {
            TopLevelWindow ww = (TopLevelWindow) page.getEnclosingWindow().getTopWindow();
            WebWindow opener = ww.getOpener();
            if (opener != null && opener != ww)
            {
                try
                {
                    ww.getJobManager().shutdown();
                    ww.close();
                }
                catch (Exception e)
                {
                }
            }
        }
    }

    /**
     * 关闭WebClient
     * @param webClient 
     */
    public static void closeWebClient(WebClient webClient)
    {
        try
        {
            webClient.close();
        }
        catch (Exception e)
        {
        }
    }
    
        /**
     * 文章链接地址修正
     *
     * @param url
     * @return
     */
    public static String resolveUrl(String url)
    {
        if(url.contains(".html"))
            url=url.substring(0, url.indexOf(".html")+5);
        else if(url.contains(".htm"))
            url=url.substring(0, url.indexOf(".htm")+4);
        return url;
    }
}
